package view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;

import model.Functie;
import model.Rol;
import model.User;
import model.factory.DAOFactory;
import persistence.dao.impl.JdbcUserDAO;
import business.exceptions.BusinessServiceException;
import business.service.UserBusinessService;
import controller.ApplicationController;
import controller.PopClickListener;

public class ApplicationView extends JFrame {

	private static final long serialVersionUID = 1L;
	private JMenu fileF;
	private JMenuBar menuBar;
	private JMenuItem newItem;
	private JMenuItem deleteItem;
	private JMenuItem cancelItem;
	private JMenuItem searchItem;
	private JPanel mainPanel;
	private JPanel topPanel;
	private JPanel bottomPanel;
	private JButton buttonPrev;
	private JButton buttonNext;
	private JButton buttonSave;
	private JLabel labelNume;
	private JTextArea textNume;
	private JLabel labelPrenume;
	private JTextArea textPrenume;
	private JLabel labelTelefon;
	private JTextArea textTelefon;
	private JLabel labelMobil;
	private JTextArea textMobil;
	private JLabel labelEmail;
	private JTextArea textEmail;
	private JLabel labelFunctie;
	private JComboBox comboFunctie;
	private JLabel labelDescriere;
	private JTextArea textDescriere;
	private JLabel labelUsername;
	private JTextArea textUsername;
	private JLabel labelPassword;
	private JPasswordField textPassword;
	private JLabel labelRol;
	private JComboBox comboRol;
	private User user;
	private ApplicationController ac;
	private JLabel status;
	private DAOFactory daoFactory;
	private UserBusinessService am;
	private JTextField searchTextField;
	private JFrame frame;
	private JList list;
	private String data[];
	private User myPersons[];

	private void initLabels() {
		labelNume = new JLabel("Nume");
		labelNume.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		textNume = new JTextArea();
		textNume.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		labelPrenume = new JLabel("Prenume");
		labelPrenume.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		textPrenume = new JTextArea();
		textPrenume.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		labelTelefon = new JLabel("Telefon");
		labelTelefon.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		textTelefon = new JTextArea();
		textTelefon.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		labelMobil = new JLabel("Mobil");
		labelMobil.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		textMobil = new JTextArea();
		textMobil.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		labelEmail = new JLabel("Email");
		labelEmail.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		textEmail = new JTextArea();
		textEmail.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		labelFunctie = new JLabel("Functie");
		labelFunctie.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		comboFunctie = new JComboBox<Object>(Functie.values());
		comboFunctie.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		labelDescriere = new JLabel("Descriere");
		labelDescriere.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		textDescriere = new JTextArea();
		textDescriere.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		labelUsername = new JLabel("Username");
		labelUsername.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		textUsername = new JTextArea();
		textUsername.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		labelPassword = new JLabel("Password");
		labelPassword.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		textPassword = new JPasswordField();
		textPassword.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		labelRol = new JLabel("Roluri");
		labelRol.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		comboRol = new JComboBox<Object>(Rol.values());
		comboRol.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		status = new JLabel("0/0");
	}

	private void initPanels() {

		mainPanel = new JPanel(new BorderLayout());
		topPanel = new JPanel(new GridLayout(0, 2, 5, 10));
		bottomPanel = new JPanel(new BorderLayout());

		mainPanel.add(topPanel, BorderLayout.NORTH);
		mainPanel.add(bottomPanel, BorderLayout.SOUTH);

	}

	private void initButtons(ApplicationController ac) {

		buttonPrev = new JButton("Previous");
		buttonSave = new JButton("Save");
		buttonNext = new JButton("Next");
		bottomPanel.add(buttonPrev, BorderLayout.LINE_START);
		bottomPanel.add(buttonNext, BorderLayout.LINE_END);
		bottomPanel.add(buttonSave, BorderLayout.CENTER);
		bottomPanel.setPreferredSize(new Dimension(100, 40));
		buttonPrev.addActionListener(ac
				.getPrevActionListener(ApplicationView.this));
		buttonSave.addActionListener(ac
				.getSaveActionListener(ApplicationView.this));
		buttonNext.addActionListener(ac
				.getNextActionListener(ApplicationView.this));
	}

	private void addComponents() {

		topPanel.add(labelNume);
		topPanel.add(textNume);
		topPanel.add(labelPrenume);
		topPanel.add(textPrenume);
		topPanel.add(labelTelefon);
		topPanel.add(textTelefon);
		topPanel.add(labelMobil);
		topPanel.add(textMobil);
		topPanel.add(labelEmail);
		topPanel.add(textEmail);
		topPanel.add(labelFunctie);
		topPanel.add(comboFunctie);
		topPanel.add(labelDescriere);
		topPanel.add(textDescriere);
		topPanel.add(labelUsername);
		topPanel.add(textUsername);
		topPanel.add(labelPassword);
		topPanel.add(textPassword);
		topPanel.add(labelRol);
		topPanel.add(comboRol);
		topPanel.add(status);
	}

	public void initMenu(ApplicationController ac) {
		menuBar = new JMenuBar();
		fileF = new JMenu();
		newItem = new JMenuItem("New");
		deleteItem = new JMenuItem("Delete");
		cancelItem = new JMenuItem("Cancel");
		searchItem = new JMenuItem("Search");
		fileF = new JMenu("File");
		menuBar.add(fileF);
		fileF.add(newItem);
		fileF.add(deleteItem);
		fileF.add(cancelItem);
		fileF.add(searchItem);
		newItem.addActionListener(ac.getNewButtonActionListener(this));
		deleteItem.addActionListener(ac.getDeleteButtonActionListener(this));
		cancelItem.addActionListener(ac.getCancelButtonActionListener(this));
		searchItem.addActionListener(ac.getSearchButtonActionListener(this));
		cancelItem.setEnabled(false);
	}

	public void resetData() {
		textNume.setText("");
		textPrenume.setText("");
		textTelefon.setText("");
		textMobil.setText("");
		textEmail.setText("");
		comboFunctie.setSelectedIndex(0);
		textDescriere.setText("");
		textUsername.setText("");
		textPassword.setText("");
		comboRol.setSelectedIndex(0);
		buttonNext.setEnabled(false);
		buttonPrev.setEnabled(false);
		cancelItem.setEnabled(true);
	}

	private boolean isValidEmailAddress(String email) {
		String ePattern = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$";
		java.util.regex.Pattern p = java.util.regex.Pattern.compile(ePattern);
		java.util.regex.Matcher m = p.matcher(email);
		return m.matches();
	}

	private boolean isPhoneNumberValid(String phoneNumber) {

		if (phoneNumber.matches("[+][0-9]+|[0-9]+") && phoneNumber.length() > 9) {
			return true;
		}
		return false;
	}

	public Object validateFields(JdbcUserDAO am, User person) {
		try {
			if (am.getMinMaxId("min") == am.getMinMaxId("max")) {
				buttonNext.setEnabled(false);
			} else
				buttonNext.setEnabled(true);
			if (am.getMinMaxId("min") == am.getMinMaxId("max")) {
				buttonPrev.setEnabled(false);
			} else {
				buttonPrev.setEnabled(true);
			}
			if (person.getNume().length() == 0) {
				JOptionPane.showMessageDialog(ApplicationView.this,
						"Numele trebuie sa fie completat!");
				return null;
			}
			if (person.getPrenume().length() == 0) {
				JOptionPane.showMessageDialog(ApplicationView.this,
						"Prenumele trebuie sa fie completat!");
				return null;
			}

			if (!isValidEmailAddress(person.getEmail())) {
				JOptionPane.showMessageDialog(ApplicationView.this,
						"Email invalid!");
				return null;
			}

			if (!isPhoneNumberValid(person.getMobil())) {
				JOptionPane
						.showMessageDialog(ApplicationView.this,
								"Numar de telefon mobil invalid! Validare 123-(456)-9999");
				return null;
			}
		}

		catch (BusinessServiceException ex) {
			JOptionPane.showMessageDialog(ApplicationView.this,
					"Eroare la baza de date");
			System.out.println(ex);
			System.exit(0);
		}
		return person;
	}

	public User getNewPerson() {

		User person = new User();
		if (user != null)
			person.setIdperson(user.getIdperson());
		person.setNume(textNume.getText());
		person.setPrenume(textPrenume.getText());
		person.setTelefon(textTelefon.getText());
		person.setMobil(textMobil.getText());
		person.setEmail(textEmail.getText());
		person.setFunctie((Functie) comboFunctie.getSelectedItem());
		person.setDescriere(textDescriere.getText());
		person.setUsername(textUsername.getText());
		person.setPassword(textPassword.getPassword().toString());
		person.setRol((Rol) comboRol.getSelectedItem());

		// if (validateFields(am, person) == null)
		// return null;

		return person;
	}

	public void setButtons() {
		int min = 0, max = 0;
		buttonPrev.setEnabled(true);
		buttonNext.setEnabled(true);
		setDelete(true);
		try {
			min = am.getMinMaxId("min");
			max = am.getMinMaxId("max");
		} catch (BusinessServiceException ex) {
			JOptionPane.showMessageDialog(ApplicationView.this,
					"Eroare la baza de date");
			System.out.println(ex);
			System.exit(0);
		}
		// System.out.println(p.getIdperson());
		if (user.getIdperson() == min) {
			buttonPrev.setEnabled(false);
		}
		if (user.getIdperson() == max) {
			buttonNext.setEnabled(false);
		}
		status.setText(am.getPosition(user.getIdperson()));
	}

	public void loadData(int id) {
		try {
			user = am.getPerson(id, " = ");
		} catch (BusinessServiceException ex) {
			JOptionPane.showMessageDialog(ApplicationView.this,
					"Eroare la baza de date");
			System.out.println(ex);
			System.exit(0);
		}

		if (user == null) {
			buttonPrev.setEnabled(false);
			buttonNext.setEnabled(false);
			deleteItem.setEnabled(false);
			return;

		}
		textNume.setText(user.getNume());
		textPrenume.setText(user.getPrenume());
		textTelefon.setText(user.getTelefon());
		textMobil.setText(user.getMobil());
		textEmail.setText(user.getEmail());
		comboFunctie.setSelectedItem(user.getFunctie());
		textDescriere.setText(user.getDescriere());
		textUsername.setText(user.getUsername());
		textPassword.setText(user.getPassword());
		comboRol.setSelectedItem(user.getRol());

		setButtons();
		this.revalidate();
	}

	public void loadData(User p) {
		if (p == null) {
			resetData();
			return;
		}

		textNume.setText(p.getNume());
		textPrenume.setText(p.getPrenume());
		textTelefon.setText(p.getTelefon());
		textMobil.setText(p.getMobil());
		textEmail.setText(p.getEmail());
		comboFunctie.setSelectedItem(p.getFunctie());
		textDescriere.setText(p.getDescriere());
		textUsername.setText(p.getUsername());
		textPassword.setText(p.getPassword());
		comboRol.setSelectedItem(p.getRol());
		this.user = p;
		setButtons();
		this.revalidate();
	}

	public void setDelete(boolean val) {
		deleteItem.setEnabled(val);
	}

	public void setPersonId(int x) {
		if (user != null) {
			user.setIdperson(x);
			deleteItem.setEnabled(true);
		}
	}

	public void setCancel(boolean bool) {
		cancelItem.setEnabled(bool);
	}

	public int getPersonId() {
		if (user != null)
			return user.getIdperson();
		else
			return 0;
	}

	public void setStatus(String status) {
		this.status.setText(status);
	}

	public String getSearchText() {
		return searchTextField.getText();
	}

	public void openSearch(ApplicationController ac) {
		frame = new JFrame("Search");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		JLabel label = new JLabel("Search:");
		searchTextField = new JTextField(10);
		searchTextField.addActionListener(ac
				.getSearchActionListener(ApplicationView.this));
		// JTextPrompt tp7 = new JTextPrompt("First Name", tf7);
		frame.getContentPane().add(label, BorderLayout.WEST);
		frame.getContentPane().add(searchTextField, BorderLayout.CENTER);
		frame.pack();
		frame.setVisible(true);
	}

	public void showSearchResults(User myPersons[], ApplicationController ac) {
		this.myPersons = myPersons;
		data = new String[myPersons.length];
		for (int i = 0; i < myPersons.length; i++) {
			if (myPersons[i] != null)
				data[i] = myPersons[i].getNume();
		}

		list = new JList(data); // data has type Object[]
		list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
		list.setLayoutOrientation(JList.HORIZONTAL_WRAP);
		list.setVisibleRowCount(-1);

		list.addMouseListener(ac.getSearchResults(ApplicationView.this));
		JScrollPane listScroller = new JScrollPane(list);
		listScroller.setPreferredSize(new Dimension(250, 80));
		frame.getContentPane().add(listScroller, BorderLayout.SOUTH);
		frame.pack();
	}

	public void getClickedPerson() {
		String userinfo;
		try {
			userinfo = list.getSelectedValue().toString();
		} catch (Exception ex) {
			return;
		}
		for (int i = 0; i < myPersons.length; i++)
			if (myPersons[i].getNume() == userinfo) {
				loadData(myPersons[i]);
				break;
			}

	}

	public ApplicationView(UserBusinessService ubs, ApplicationController ac) {
		// ide kell a service

		am = ubs;
		// am = service.getService();

		PopUpMenu p = new PopUpMenu(this, ac);
		this.ac = ac;
		this.setLayout(null);
		this.setTitle("User management");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		initPanels();
		initMenu(ac);
		initLabels();
		initButtons(ac);
		addComponents();
		mainPanel.addMouseListener(new PopClickListener(this, ac));

		this.setContentPane(mainPanel);

		setJMenuBar(menuBar);
		loadData(0);

	}

}
